// 版权所有 Epic Games, Inc. 保留所有权利。

#pragma once

#include "Engine/StreamableManager.h"

DECLARE_DELEGATE_OneParam(FLyraAssetManagerStartupJobSubstepProgress, float /*新进度*/); // 声明单参数委托：启动任务子步骤进度

/** 处理来自流式处理句柄的进度报告 */
struct FLyraAssetManagerStartupJob
{
	FLyraAssetManagerStartupJobSubstepProgress SubstepProgressDelegate; // 子步骤进度委托
	TFunction<void(const FLyraAssetManagerStartupJob&, TSharedPtr<FStreamableHandle>&)> JobFunc; // 任务函数
	FString JobName; // 任务名称
	float JobWeight; // 任务权重
	mutable double LastUpdate = 0; // 最后更新时间

	/** 所有同步的简单任务 */
	FLyraAssetManagerStartupJob(const FString& InJobName, const TFunction<void(const FLyraAssetManagerStartupJob&, TSharedPtr<FStreamableHandle>&)>& InJobFunc, float InJobWeight)
		: JobFunc(InJobFunc) // 初始化任务函数
		, JobName(InJobName) // 初始化任务名称
		, JobWeight(InJobWeight) // 初始化任务权重
	{}

	/** 执行实际加载，如果创建了句柄将返回一个句柄 */
	TSharedPtr<FStreamableHandle> DoJob() const;

	void UpdateSubstepProgress(float NewProgress) const // 更新子步骤进度
	{
		SubstepProgressDelegate.ExecuteIfBound(NewProgress); // 如果绑定则执行委托
	}

	void UpdateSubstepProgressFromStreamable(TSharedRef<FStreamableHandle> StreamableHandle) const // 从流式处理更新子步骤进度
	{
		if (SubstepProgressDelegate.IsBound()) // 检查委托是否绑定
		{
			// StreamableHandle::GetProgress遍历()一个大图并且相当昂贵
			double Now = FPlatformTime::Seconds(); // 获取当前时间
			if (LastUpdate - Now > 1.0 / 60) // 检查更新时间间隔
			{
				SubstepProgressDelegate.Execute(StreamableHandle->GetProgress()); // 执行委托传递进度
				LastUpdate = Now; // 更新最后更新时间
			}
		}
	}
};